import {mapGetters} from 'vuex';
import {reactive} from 'vue'
import {downloadXls, deepAssign} from '@/utils/util';
import {getToken} from '@/utils/auth';
import {exportBlob} from '@/api/common';
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';

export const ListMixin = {
    data() {
        return {
            form: {},
            selectionId: '',
            selectionList: [],
            query: {},
            loading: true,
            page: {
                pageSize: 10,
                currentPage: 1,
                total: 0,
            },
            data: [],
            // 配置项
            defaultListMixinConfig: {
                // 对应的api目录下 js文件
                api: "", // == @/api/demo/demo_api.js
                // 对应api中方法名称  默认与属性名相同
                apiProps: {
                    getList: "getList",  // 默认为"getList"
                    add: "add",
                    update: "update",
                    getDetail: "getDetail",
                    remove: "remove",
                },
                // 导出excel配置
                export: {
                    // 导出的名称
                    name: "",
                    // url
                    url: "",
                },
                // ----------------------以下默认fase
                // 禁止使用默认 用于自定义
                disableOnLoad: false, // 对应方法"onLoad", 如果为true,可重写“onLoad”方法, 参数（page, params = {}）
                // 禁止使用默认保存 用于自定义
                disableRowSave: false, // 对应方法"rowSave", 如果为true,可重写“rowSave”方法, 参数（row, done, loading）
                // 禁止使用默认更新 用于自定义
                disableRowUpdate: false, // 对应方法"rowUpdate", 如果为true,可重写“rowUpdate”方法, 参数（row, index, done, loading）
                // 禁止使用默认 打开窗口 用于自定义
                disableBeforeOpen: false, // 对应方法"beforeOpen", 如果为true,可重写“beforeOpen”方法, 参数（done, type）
                // 禁止使用默认 删除 用于自定义
                disableRowDel: false, // 对应方法"rowDel", 如果为true,可重写“rowDel”方法, 参数（row）
                // 禁止使用默认 批量删除 用于自定义
                disableHandleDelete: false, // 对应方法"handleDelete", 如果为true,可重写“handleDelete”方法, 参数（）
                // 禁止使用默认 导出数据 用于自定义
                disableHandleExport: false, // 对应方法"handleExport", 如果为true,可重写“handleExport”方法, 参数（）
            },
            listMixinConfig: {},
            // Api 接口对象
            apiModule: {},
        }
    },
    created() {
        this.configBefore();
        this.listMixinConfig = deepAssign(this.defaultListMixinConfig, this.listMixinConfig);

        if (!this.listMixinConfig.api) {
            throw new Error("请配置listMixinConfig.api");
        }
        this.apiModule = window.$globApi[`./api/${this.listMixinConfig.api}.js`];
        if (!this.apiModule) {
            throw new Error(`未找到对应api文件(${this.listMixinConfig.api}.js)`);
        }
    },
    computed: {
        ...mapGetters(['permission']),
        ids() {
            let ids = [];
            this.selectionList.forEach(ele => {
                ids.push(ele.id);
            });
            return ids.join(',');
        },
        // 需重写权限
        permissionList() {
            return {
                addBtn: false,
                viewBtn: false,
                delBtn: false,
                editBtn: false,
            };
        },
    },
    methods: {
        /**
         * 配置创建之前，可对config进行相关操作
         */
        configBefore() {

        },
        rowSave(row, done, loading) {
            if (!this.listMixinConfig.disableRowSave) {
                const apiName = this.listMixinConfig.apiProps.add || "add";
                let api = this.apiModule[apiName];
                if (api) {
                    if (this.addBefore) {
                        // 如果返回true, 终止执行
                        if (this.addBefore(row, done, loading)) {
                            return;
                        }
                    }
                    api(row).then(
                        () => {
                            this.onLoad(this.page);
                            this.$message({
                                type: 'success',
                                message: '操作成功!',
                            });
                            done();

                            if (this.addAfter) {
                                this.addAfter();
                            }
                        },
                        error => {
                            loading();
                            if (this.addError) {
                                this.addError(error);
                            }
                        }
                    );
                } else {
                    throw new Error(`${this.listMixinConfig.api} 没有 ${apiName} 方法`)
                }
            }
        },
        rowUpdate(row, index, done, loading) {
            if (!this.listMixinConfig.disableRowUpdate) {
                const apiName = this.listMixinConfig.apiProps.update || "update";
                let api = this.apiModule[apiName];
                if (api) {
                    if (this.updateBefore) {
                        // 如果返回true, 终止执行
                        if (this.updateBefore(row, index, done, loading)) {
                            return;
                        }
                    }
                    api(row).then(
                        () => {
                            this.onLoad(this.page);
                            this.$message({
                                type: 'success',
                                message: '操作成功!',
                            });
                            done();

                            if (this.updateAfter) {
                                this.updateAfter();
                            }
                        },
                        error => {
                            loading();
                            if (this.updateError) {
                                this.updateError(error);
                            }
                        }
                    );
                } else {
                    throw new Error(`${this.listMixinConfig.api} 没有 ${apiName} 方法`)
                }
            }
        },
        rowDel(row) {
            if (!this.listMixinConfig.disableRowDel) {
                const apiName = this.listMixinConfig.apiProps.remove || "remove";
                let api = this.apiModule[apiName];
                if (api) {
                    if (this.removeBefore) {
                        // 如果返回true, 终止执行
                        if (this.removeBefore(row)) {
                            return;
                        }
                    }
                    this.$confirm('确定将选择数据删除?', {
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        type: 'warning',
                    })
                        .then(() => {
                            return api(row.id);
                        })
                        .then(() => {
                            this.onLoad(this.page);
                            this.$message({
                                type: 'success',
                                message: '操作成功!',
                            });
                            if (this.removeAfter) {
                                this.removeAfter();
                            }
                        }, error => {
                            if (this.removeError) {
                                this.removeError(error);
                            }
                        });
                } else {
                    throw new Error(`${this.listMixinConfig.api} 没有 ${apiName} 方法`)
                }
            }
        },
        handleDelete() {
            if (this.selectionList.length === 0) {
                this.$message.warning('请选择至少一条数据');
                return;
            }
            if (!this.listMixinConfig.disableHandleDelete) {
                const apiName = this.listMixinConfig.apiProps.remove || "remove";
                let api = this.apiModule[apiName];
                if (api) {
                    if (this.removeBatchBefore) {
                        // 如果返回true, 终止执行
                        if (this.removeBatchBefore()) {
                            return;
                        }
                    }
                    this.$confirm('确定将选择数据删除?', {
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        type: 'warning',
                    })
                        .then(() => {
                            return api(this.ids);
                        })
                        .then(() => {
                            this.onLoad(this.page);
                            this.$message({
                                type: 'success',
                                message: '操作成功!',
                            });
                            this.$refs.crud.toggleSelection();
                            if (this.removeBatchAfter) {
                                this.removeBatchAfter();
                            }
                        }, error => {
                            if (this.removeBatchError) {
                                this.removeBatchError(error);
                            }
                        });
                } else {
                    throw new Error(`${this.listMixinConfig.api} 没有 ${apiName} 方法`)
                }
            }
        },
        beforeOpen(done, type) {
            if (!this.listMixinConfig.disableBeforeOpen) {
                if (this.detailBefore) {
                    // 如果返回true, 终止执行
                    if (this.detailBefore(done, type)) {
                        return;
                    }
                }
                if (['edit', 'view'].includes(type)) {
                    const apiName = this.listMixinConfig.apiProps.getDetail || "getDetail";
                    let api = this.apiModule[apiName];
                    if (api) {
                        api(this.form.id).then(res => {
                            this.form = res.data.data;
                            if (this.detailAfter) {
                                if(!this.detailAfter(type)) {
                                    done();
                                }
                            }
                        }, error => {
                            if (this.detailError) {
                                this.detailError(error);
                            }
                        });
                    } else {
                        throw new Error(`${this.listMixinConfig.api} 没有 ${apiName} 方法`)
                    }
                } else {
                    if (this.detailAfter) {
                        if(!this.detailAfter(type)) {
                            done();
                        }
                    }
                }
            }
        },
        handleExport() {
            if (!this.listMixinConfig.disableHandleExport) {
                this.$confirm(`是否导出${this.listMixinConfig.export.name}?`, '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning',
                }).then(() => {
                    let query = {
                        [this.website.tokenHeader]: getToken()
                    };
                    if (this.exportBefore && this.exportBefore(query)) {
                        return;
                    }
                    let queryStr = "";
                    for (let key in query) {
                        queryStr += `${key}=${query[key]}&`
                    }
                    NProgress.start();
                    exportBlob(
                        `${this.listMixinConfig.export.url}?${queryStr}`
                    ).then(res => {
                        downloadXls(res.data, `${this.listMixinConfig.export.name}_${this.$dayjs().format('YYYY-MM-DD HH:mm:ss')}.xlsx`);
                        NProgress.done();
                    }, error => {
                        if (this.exportError) {
                            this.exportError(error);
                        }
                    });
                });
            }
        },
        searchReset() {
            this.query = {};
            this.onLoad(this.page);
        },
        searchChange(params, done) {
            this.query = params;
            this.page.currentPage = 1;
            this.onLoad(this.page, params);
            done();
        },
        selectionChange(list) {
            this.selectionList = list;
        },
        selectionClear() {
            this.selectionList = [];
            this.$refs.crud.toggleSelection();
        },
        currentChange(currentPage) {
            this.page.currentPage = currentPage;
        },
        sizeChange(pageSize) {
            this.page.pageSize = pageSize;
        },
        refreshChange() {
            this.onLoad(this.page, this.query);
        },
        onLoad(page, params = {}) {
            if (!this.listMixinConfig.disableOnLoad) {
                const apiName = this.listMixinConfig.apiProps.getList || "getList";
                let api = this.apiModule[apiName];
                if (api) {
                    // 如果listBefore返回true, 终止执行
                    if (this.onLoadBefore && this.onLoadBefore(page, params = {})) {
                        return;
                    }
                    const query = {
                        ...this.query
                    };
                    this.loading = true;
                    api(page.currentPage, page.pageSize, Object.assign(params, query)).then(res => {
                        const data = res.data.data;
                        this.page.total = data.total;
                        this.data = data.records;
                        this.loading = false;
                        this.selectionClear();
                        if (this.onLoadAfter) {
                            this.onLoadAfter(data);
                        }
                    }, error => {
                        if (this.onLoadError) {
                            this.onLoadError(error);
                        }
                    });
                } else {
                    throw new Error(`${this.listMixinConfig.api} 没有 ${apiName} 方法`)
                }
            }
        },
    }
};
